

char Corr_time;
int gg1, mm1, dd1, gg2, mm2, dd2, hr1, hr2;

long New_Hours = 0;
long New_minutes = 0;
long New_seconds = 0;
long Corr_time_long = 0;
long JD1 = 0;
long JD2 = 0;
int LeapYear;
 
 
  Corr_time = EEPROM.read(0); // we read from the non-volatile memory the value of the error of the clock
  if (Corr_time > 60 || Corr_time < -60) Corr_time = 0; // if the time correction is more/less than a minute, then the device is turned on for the first time, then set the value of the variable 0

  dd1 = EEPROM.read(1); // we read from non-volatile memory the number of the month when the clock was last adjusted
  if (dd1 > 31 || dd1 < 0) {
    dd1 = time.day;
    EEPROM.write(1, dd1);
  }

  mm1 = EEPROM.read(2); // we read from non-volatile memory the month when the clock was last adjusted
  if (mm1 > 12 || mm1 < 0) {
    mm1 = time.month;
    EEPROM.write(2, mm1);
  }

  gg1 = EEPROM.read(3); // we read from non-volatile memory the year when the clock was last adjusted
  if (gg1 > 73 || gg1 < 0) {
    gg1 = time.year;
    EEPROM.write(3, gg1);
  }

  hr1 = EEPROM.read(4); // we read from the non-volatile memory the hour when the clock was last adjusted
  if (hr1 > 24 || hr1 < 0) {
    hr1 = time.Hours;
    EEPROM.write(4, hr1);
  }

  dd2 = time.day; // assign the current time and date to the intermediate variables
  mm2 = time.month;
  gg2 = time.year;
  hr2 = time.Hours;

// we determine the Julian date for the moment of the last adjustment of the clock
  if (mm1 < 3) {
    JD1 = int((gg1 - 1) * 365.25) + int((mm1 + 12) * 30.6 + (float)0.7) + dd1;
  }
  else {
    JD1 = int(gg1 * 365.25) + int(mm1 * 30.6 + (float)0.7) + dd1;
  }

// we determine the Julian date for the current system time in the clock (our device)
  if (mm2 < 3) {
    JD2 = int((gg2 - 1) * 365.25) + int((mm2 + 12) * 30.6 + (float)0.7) + dd2;
  }
  else {
    JD2 = int(gg2 * 365.25) + int(mm2 * 30.6 + (float)0.7) + dd2;
  }
// we determine the number of hours that have passed since the last time correction
  if (hr2 >= hr1) {
    Corr_time_long = round(((long)24 * (JD2 - JD1) + hr2 - hr1) * ((float)Corr_time / 24));
  }
  else {
    Corr_time_long = round(((long)24 * (JD2 - JD1 - 1) + (24 + hr2 - hr1)) * ((float)Corr_time / 24));
  }

  //we translate the current system time into seconds and add an adjustment taking into account the accuracy of the stroke
  long Total_new_sec = (long)time.Hours * 3600 + (long)time.minutes * 60 + time.seconds + Corr_time_long;
  
  if (Total_new_sec >= 0) {
    Num_day = int((long)Total_new_sec / 86400);
  }
  else {
    Num_day = -1 + int((long)Total_new_sec / 86400);
  }

  if (Total_new_sec > 0) {

    for (int nd = 0; nd < Num_day; nd++) {

      if (time.month == 2) {
        LeapYear = 0;  //definition of a leap year
        if ( (((2000 + int(time.year)) % 4) == 0) & (((2000 + int(time.year)) % 100) != 0)  || (((2000 + int(time.year)) % 400) == 0) ) {
          LeapYear = 1;
        }
        else {
          LeapYear = 0;
        }
      }

      if ((time.day == 31) & (time.month == 1 || time.month == 3 || time.month == 5 || time.month == 7 || time.month == 8 || time.month == 10 || time.month == 12))
      { time.day = 1;
        if (time.month < 12) {
          time.month++;
          time.weekday++;
        }
        else {
          time.month = 1;
          time.weekday++;
          time.year++;
        }
      }
      else if ((time.day == 30) & (time.month == 4 || time.month == 6 || time.month == 9 || time.month == 11))
      { time.day = 1;
        time.month++;
        time.weekday++;
      }
      else if ((time.day == 29) & (time.month == 2) & (LeapYear == 1) )
      { time.day = 1;
        time.month++;
        time.weekday++;
      }
      else if ((time.day == 28) & (time.month == 2) & (LeapYear == 0) )
      { time.day = 1;
        time.month++;
        time.weekday++;
      }
      else
      {
        time.day ++;
        time.weekday++;
      }
    }
  }

  if (Total_new_sec < 0) {

    Num_day = abs(Num_day);

    for (int nd = 0; nd < Num_day; nd++) {

      if (time.day == 1)
      {
        if ((time.month == 1 || time.month == 3 || time.month == 5 || time.month == 7 || time.month == 8 || time.month == 10 || time.month == 12))
        { time.day = 31;
          time.month--;
          time.weekday--;
          if (time.month = 1) {
            time.year--;
          }
        }
        else if ((time.month == 4 || time.month == 6 || time.month == 9 || time.month == 11))
        { time.day = 30;
          time.month--;
          time.weekday--;
        }
        else if ((time.month == 2) & (LeapYear == 0))
        { time.day = 29;
          time.month--;
          time.weekday--;
        }
        else if ((time.month == 2) & (LeapYear == 0) )
        { time.day = 28;
          time.month--;
          time.weekday--;
        }
      }
      else
      {
        time.day --;
        time.weekday--;
      }
    }
  }


  ////////////////////////date correction ///////////////////////////////////////////////

  Corr_time_long = Corr_time_long -  int((long)Corr_time_long / 86400) * 86400;

  long new_sec = (long)time.Hours * 3600 + (long)time.minutes * 60 + time.seconds + Corr_time_long;

  if (new_sec < 0) {
    New_Hours = 23;
    New_minutes = 59;
    New_seconds = 60 + time.minutes + new_sec;
  }
  if (new_sec > 0) {
    New_Hours = int ((long)new_sec / 3600);
    New_minutes = int ((long)(new_sec - (long)New_Hours * 3600) / 60);
    New_seconds = new_sec - (long)New_Hours * 3600 - (long)New_minutes * 60;
  }

  if (New_Hours > 23) New_Hours = New_Hours - 24;

  time.Hours = New_Hours;
  time.minutes = New_minutes;
  time.seconds = New_seconds;

  /////////////////////////////////defining a new date and day of the week//////////////////

  time.settime(time.seconds, time.minutes, time.Hours, time.day, time.month, time.year, time.weekday);

  time.gettime("d-m-Y, H:i:s, D");

  dd2 = time.day;
  mm2 = time.month;
  gg2 = time.year;
  hr2 = time.Hours;

// we record the date and time of the clock correction in the non-volatile memory of the device
  EEPROM.write(1, dd2);
  EEPROM.write(2, mm2);
  EEPROM.write(3, gg2);
  EEPROM.write(4, hr2);
